﻿using System;
using System.Collections.Generic;
using System.Linq;
using EzDesk.Apps.Model.Attendance;

namespace EzDesk.Apps.ServiceImpl.Attendance.Evaluation
{
    public sealed class DayAttendanceEvaluatorEx : DayAttendanceEvaluatorBase
    {
        private DayLeaveInfo _dayLeaveInfo;
        private Guid _userId;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="config"></param>
        /// <param name="attendanceInfoList">要传入72小时所有的考勤记录</param>
        /// <param name="dayInfo"></param>
        /// <param name="dayLeaveInfo"></param>
        public DayAttendanceEvaluatorEx(
            Guid userId,
            DayInfo dayInfo,
            AttendanceConfig config,
            List<AttendanceInfo> attendanceInfoList,
            DayLeaveInfo dayLeaveInfo
            )
        {
            if (dayLeaveInfo == null)
            {
                dayLeaveInfo = new DayLeaveInfo(dayInfo.Date);
            }
            if (attendanceInfoList == null)
            {
                attendanceInfoList = new List<AttendanceInfo>();
            }

            Config = config;
            AttendanceInfoList = attendanceInfoList;
            DayInfo = dayInfo;

            _userId = userId;
            _dayLeaveInfo = dayLeaveInfo;
        }

        public override DayAttendanceEvaluation GetAttendanceEvaluation()
        {
            var lateAndEarly = CalculateLateAndEarlyMinutes();
            // 初始化对象
            var resultEvaluationInfo = new DayAttendanceEvaluation
            {
                Id = Guid.Empty,
                UserId = _userId,
                Date = DayInfo.Date,
                IsNeedToWork = DayInfo.IsNeedToWork,
                LateMiniutes = lateAndEarly.LateMiniutes,
                EarlyMiniutes = lateAndEarly.EarlyMiniutes,
                Manhours = CalculateManhours(),
                IsAbsense = IsAbsenseToday(),
                IsExtraWork = IsExtraWorkToday(),
                LeaveInfo = _dayLeaveInfo,
                DayAttendanceInfoList = TodayAttendanceList,
            };
            return resultEvaluationInfo;
        }


        public override int CalculateManhours()
        {
            var manhourMiniutes = base.CalculateManhours();
            var lateAndEarly = CalculateLateAndEarlyMinutes();

            var maxManhours = (int)(Config.StdManhours.TotalMinutes);
            
            // 全天工作假期
            if (_dayLeaveInfo.HasLeave && _dayLeaveInfo.IsWholeDay && _dayLeaveInfo.FirstLeave.IsForWork)
            {
                manhourMiniutes = maxManhours;
            }
            else if (!_dayLeaveInfo.IsWholeDay)
            {
                // 没有全天请假的情况，把工作假期算作为工时
                _dayLeaveInfo.Leaves.ForEach(
                    leaveinfoItem =>
                        {
                            if (leaveinfoItem.IsForWork)
                            {
                                manhourMiniutes += (int)(leaveinfoItem.EndTime - leaveinfoItem.StartTime).TotalMinutes;
                            }
                        }
                    );
            }

            // todo: 考虑加班的情况

            var firstOnDutyInfo = FirstOnDutyInfo;
            var lastOffDutyInfo = LastOffDutyInfo;
            // 去掉加班的时间
            var workTimetable = GetWorkingTimeTable(FirstOnDutyInfo, LastOffDutyInfo);
            if (lastOffDutyInfo != null && lastOffDutyInfo.ActionTime > workTimetable.StdOffDutyTime)
            {
                manhourMiniutes -= (int)(lastOffDutyInfo.ActionTime - workTimetable.StdOffDutyTime).TotalMinutes;
            }
            if (firstOnDutyInfo != null && firstOnDutyInfo.ActionTime < workTimetable.StdOnDutyTime)
            {
                manhourMiniutes -= (int)(workTimetable.StdOnDutyTime - firstOnDutyInfo.ActionTime).TotalMinutes;
            }


            // 8小时封顶，最多0小时

            if (manhourMiniutes > maxManhours)
            {
                manhourMiniutes = maxManhours;
            }

            if (manhourMiniutes < 0)
            {
                manhourMiniutes = 0;
            }

            return manhourMiniutes;
        }

        public override bool IsAbsenseToday()
        {
            var isAbsence = base.IsAbsenseToday();
            if (isAbsence)
            {
                if (_dayLeaveInfo.HasLeave)
                {
                    isAbsence = false;
                }
            }

            return isAbsence;
        }


        protected override DayWorkingTimeTable GetWorkingTimeTable(AttendanceInfo firstOnDutyInfo, AttendanceInfo lastOffDutyInfo)
        {
            var timeTable = base.GetWorkingTimeTable(firstOnDutyInfo, lastOffDutyInfo);
            _dayLeaveInfo.Leaves.ForEach(
                leaveinfoItem =>
                    {
                        // 根据当日的假期状况，计算新的标准上下班时间
                        if (timeTable.StdOnDutyTime >= leaveinfoItem.StartTime && timeTable.StdOnDutyTime <= leaveinfoItem.EndTime)
                        {
                            timeTable.StdOnDutyTime = leaveinfoItem.EndTime;
                        }
                        if (timeTable.StdOffDutyTime >= leaveinfoItem.StartTime && timeTable.StdOffDutyTime <= leaveinfoItem.EndTime)
                        {
                            timeTable.StdOffDutyTime = leaveinfoItem.StartTime;
                        }
                    });
            return timeTable;
        }

        
    }
}
